from PyQt6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                             QSplitter, QTabWidget, QMenuBar, QToolBar, QStatusBar,
                             QMessageBox, QFileDialog, QInputDialog)
from PyQt6.QtCore import Qt, QTimer, pyqtSignal
from PyQt6.QtGui import QIcon, QKeySequence, QAction
from loguru import logger
from typing import Optional
import asyncio
import sys
from pathlib import Path

# 添加项目根目录到路径
sys.path.insert(0, str(Path(__file__).parent.parent))

from .widgets.script_list_widget import ScriptListWidget
from .widgets.script_editor_widget import ScriptEditorWidget
from .widgets.recording_widget import RecordingWidget
from .widgets.execution_widget import ExecutionWidget
from .widgets.settings_widget import SettingsWidget
from backend.script_manager import ScriptManager
from backend.recorder import PlaywrightRecorder
from backend.script_generator import ScriptGenerator
from backend.executor import ScriptExecutor
from config.settings import get_settings


class MainWindow(QMainWindow):
    """主窗口"""
    
    # 信号定义
    script_selected = pyqtSignal(str)  # 脚本选中信号
    recording_started = pyqtSignal()   # 录制开始信号
    recording_stopped = pyqtSignal()   # 录制停止信号
    
    def __init__(self):
        super().__init__()
        self.settings = get_settings()
        
        # 核心组件
        self.script_manager = ScriptManager(self.settings.scripts_dir)
        self.recorder: Optional[PlaywrightRecorder] = None
        self.script_generator = ScriptGenerator()
        self.script_executor = ScriptExecutor()
        
        # 界面组件
        self.script_list_widget: Optional[ScriptListWidget] = None
        self.script_editor_widget: Optional[ScriptEditorWidget] = None
        self.recording_widget: Optional[RecordingWidget] = None
        self.execution_widget: Optional[ExecutionWidget] = None
        self.settings_widget: Optional[SettingsWidget] = None
        
        # 当前状态
        self.current_script_id: Optional[str] = None
        self.is_recording = False
        
        self.init_ui()
        self.setup_connections()
        
        logger.info("主窗口初始化完成")
    
    def init_ui(self):
        """初始化界面"""
        self.setWindowTitle(self.settings.app_name)
        self.setGeometry(100, 100, self.settings.window_width, self.settings.window_height)
        
        # 创建菜单栏
        self.create_menu_bar()
        
        # 创建工具栏
        self.create_tool_bar()
        
        # 创建中央窗口
        self.create_central_widget()
        
        # 创建状态栏
        self.create_status_bar()
        
        # 应用样式
        self.apply_styles()
    
    def create_menu_bar(self):
        """创建菜单栏"""
        menubar = self.menuBar()
        
        # 文件菜单
        file_menu = menubar.addMenu("文件(&F)")
        
        new_script_action = QAction("新建脚本(&N)", self)
        new_script_action.setShortcut(QKeySequence.StandardKey.New)
        new_script_action.triggered.connect(self.new_script)
        file_menu.addAction(new_script_action)
        
        open_script_action = QAction("打开脚本(&O)", self)
        open_script_action.setShortcut(QKeySequence.StandardKey.Open)
        open_script_action.triggered.connect(self.open_script)
        file_menu.addAction(open_script_action)
        
        file_menu.addSeparator()
        
        save_script_action = QAction("保存脚本(&S)", self)
        save_script_action.setShortcut(QKeySequence.StandardKey.Save)
        save_script_action.triggered.connect(self.save_current_script)
        file_menu.addAction(save_script_action)
        
        file_menu.addSeparator()
        
        import_action = QAction("导入脚本(&I)", self)
        import_action.triggered.connect(self.import_script)
        file_menu.addAction(import_action)
        
        export_action = QAction("导出脚本(&E)", self)
        export_action.triggered.connect(self.export_script)
        file_menu.addAction(export_action)
        
        file_menu.addSeparator()
        
        exit_action = QAction("退出(&X)", self)
        exit_action.setShortcut(QKeySequence.StandardKey.Quit)
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)
        
        # 编辑菜单
        edit_menu = menubar.addMenu("编辑(&E)")
        
        undo_action = QAction("撤销(&U)", self)
        undo_action.setShortcut(QKeySequence.StandardKey.Undo)
        edit_menu.addAction(undo_action)
        
        redo_action = QAction("重做(&R)", self)
        redo_action.setShortcut(QKeySequence.StandardKey.Redo)
        edit_menu.addAction(redo_action)
        
        edit_menu.addSeparator()
        
        copy_action = QAction("复制(&C)", self)
        copy_action.setShortcut(QKeySequence.StandardKey.Copy)
        edit_menu.addAction(copy_action)
        
        paste_action = QAction("粘贴(&V)", self)
        paste_action.setShortcut(QKeySequence.StandardKey.Paste)
        edit_menu.addAction(paste_action)
        
        # 录制菜单
        record_menu = menubar.addMenu("录制(&R)")
        
        start_record_action = QAction("开始录制(&S)", self)
        start_record_action.setShortcut("Ctrl+R")
        start_record_action.triggered.connect(self.start_recording)
        record_menu.addAction(start_record_action)
        
        stop_record_action = QAction("停止录制(&T)", self)
        stop_record_action.setShortcut("Ctrl+T")
        stop_record_action.triggered.connect(self.stop_recording)
        record_menu.addAction(stop_record_action)
        
        # 运行菜单
        run_menu = menubar.addMenu("运行(&R)")
        
        run_script_action = QAction("运行脚本(&R)", self)
        run_script_action.setShortcut("F5")
        run_script_action.triggered.connect(self.run_current_script)
        run_menu.addAction(run_script_action)
        
        stop_script_action = QAction("停止脚本(&S)", self)
        stop_script_action.setShortcut("Ctrl+F5")
        stop_script_action.triggered.connect(self.stop_script_execution)
        run_menu.addAction(stop_script_action)
        
        # 工具菜单
        tools_menu = menubar.addMenu("工具(&T)")
        
        settings_action = QAction("设置(&S)", self)
        settings_action.triggered.connect(self.show_settings)
        tools_menu.addAction(settings_action)
        
        # 帮助菜单
        help_menu = menubar.addMenu("帮助(&H)")
        
        about_action = QAction("关于(&A)", self)
        about_action.triggered.connect(self.show_about)
        help_menu.addAction(about_action)
    
    def create_tool_bar(self):
        """创建工具栏"""
        toolbar = self.addToolBar("主工具栏")
        
        # 新建脚本
        new_action = QAction("新建", self)
        new_action.setToolTip("新建脚本")
        new_action.triggered.connect(self.new_script)
        toolbar.addAction(new_action)
        
        # 打开脚本
        open_action = QAction("打开", self)
        open_action.setToolTip("打开脚本")
        open_action.triggered.connect(self.open_script)
        toolbar.addAction(open_action)
        
        # 保存脚本
        save_action = QAction("保存", self)
        save_action.setToolTip("保存脚本")
        save_action.triggered.connect(self.save_current_script)
        toolbar.addAction(save_action)
        
        toolbar.addSeparator()
        
        # 开始录制
        record_action = QAction("录制", self)
        record_action.setToolTip("开始录制")
        record_action.triggered.connect(self.start_recording)
        toolbar.addAction(record_action)
        
        # 停止录制
        stop_record_action = QAction("停止", self)
        stop_record_action.setToolTip("停止录制")
        stop_record_action.triggered.connect(self.stop_recording)
        toolbar.addAction(stop_record_action)
        
        toolbar.addSeparator()
        
        # 运行脚本
        run_action = QAction("运行", self)
        run_action.setToolTip("运行脚本")
        run_action.triggered.connect(self.run_current_script)
        toolbar.addAction(run_action)
        
        # 停止执行
        stop_action = QAction("停止执行", self)
        stop_action.setToolTip("停止脚本执行")
        stop_action.triggered.connect(self.stop_script_execution)
        toolbar.addAction(stop_action)
    
    def create_central_widget(self):
        """创建中央窗口"""
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 创建主布局
        main_layout = QHBoxLayout(central_widget)
        
        # 创建分割器
        splitter = QSplitter(Qt.Orientation.Horizontal)
        main_layout.addWidget(splitter)
        
        # 左侧：脚本列表
        self.script_list_widget = ScriptListWidget(self.script_manager)
        splitter.addWidget(self.script_list_widget)
        
        # 右侧：标签页
        self.tab_widget = QTabWidget()
        splitter.addWidget(self.tab_widget)
        
        # 脚本编辑器标签页
        self.script_editor_widget = ScriptEditorWidget()
        self.tab_widget.addTab(self.script_editor_widget, "脚本编辑")
        
        # 录制标签页
        self.recording_widget = RecordingWidget()
        self.tab_widget.addTab(self.recording_widget, "录制")
        
        # 执行结果标签页
        self.execution_widget = ExecutionWidget()
        self.tab_widget.addTab(self.execution_widget, "执行结果")
        
        # 设置标签页
        self.settings_widget = SettingsWidget()
        self.tab_widget.addTab(self.settings_widget, "设置")
        
        # 设置分割器比例
        splitter.setSizes([300, 800])
    
    def create_status_bar(self):
        """创建状态栏"""
        self.status_bar = self.statusBar()
        self.status_bar.showMessage("就绪")
        
        # 添加状态指示器
        self.recording_status_label = self.status_bar.addPermanentWidget(None)
        self.execution_status_label = self.status_bar.addPermanentWidget(None)
    
    def apply_styles(self):
        """应用样式"""
        if self.settings.theme == "dark":
            self.setStyleSheet("""
                QMainWindow {
                    background-color: #2b2b2b;
                    color: #ffffff;
                }
                QTabWidget::pane {
                    border: 1px solid #444444;
                }
                QTabBar::tab {
                    background-color: #3c3c3c;
                    color: #ffffff;
                    padding: 8px 16px;
                }
                QTabBar::tab:selected {
                    background-color: #4a4a4a;
                }
            """)
    
    def setup_connections(self):
        """设置信号连接"""
        # 脚本列表选择信号
        self.script_list_widget.script_selected.connect(self.on_script_selected)
        self.script_list_widget.script_double_clicked.connect(self.on_script_double_clicked)
        
        # 脚本编辑器信号
        self.script_editor_widget.script_changed.connect(self.on_script_changed)
        
        # 录制器信号
        self.recording_widget.start_recording.connect(self.start_recording)
        self.recording_widget.stop_recording.connect(self.stop_recording)
        
        # 执行器信号
        self.execution_widget.run_script.connect(self.run_current_script)
        self.execution_widget.stop_execution.connect(self.stop_script_execution)
    
    def on_script_selected(self, script_id: str):
        """脚本选择事件"""
        self.current_script_id = script_id
        script = self.script_manager.get_script(script_id)
        if script:
            self.script_editor_widget.load_script(script)
            self.status_bar.showMessage(f"已选择脚本: {script.name}")
    
    def on_script_double_clicked(self, script_id: str):
        """脚本双击事件"""
        self.current_script_id = script_id
        script = self.script_manager.get_script(script_id)
        if script:
            self.script_editor_widget.load_script(script)
            self.tab_widget.setCurrentWidget(self.script_editor_widget)
    
    def on_script_changed(self):
        """脚本内容改变事件"""
        if self.current_script_id:
            self.status_bar.showMessage("脚本已修改")
    
    def new_script(self):
        """新建脚本"""
        name, ok = QInputDialog.getText(self, "新建脚本", "请输入脚本名称:")
        if ok and name:
            from backend.models import ScriptModel
            script = ScriptModel(name=name)
            if self.script_manager.save_script(script):
                self.script_list_widget.refresh_scripts()
                self.current_script_id = script.id
                self.script_editor_widget.load_script(script)
                self.status_bar.showMessage(f"已创建新脚本: {name}")
    
    def open_script(self):
        """打开脚本"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "打开脚本", "", "JSON文件 (*.json)"
        )
        if file_path:
            script = self.script_manager.import_script(file_path)
            if script:
                self.script_list_widget.refresh_scripts()
                self.current_script_id = script.id
                self.script_editor_widget.load_script(script)
                self.status_bar.showMessage(f"已打开脚本: {script.name}")
    
    def save_current_script(self):
        """保存当前脚本"""
        if self.current_script_id:
            script = self.script_editor_widget.get_current_script()
            if script and self.script_manager.save_script(script):
                self.script_list_widget.refresh_scripts()
                self.status_bar.showMessage(f"已保存脚本: {script.name}")
    
    def import_script(self):
        """导入脚本"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "导入脚本", "", "JSON文件 (*.json)"
        )
        if file_path:
            script = self.script_manager.import_script(file_path)
            if script:
                self.script_list_widget.refresh_scripts()
                self.status_bar.showMessage(f"已导入脚本: {script.name}")
    
    def export_script(self):
        """导出脚本"""
        if not self.current_script_id:
            QMessageBox.warning(self, "警告", "请先选择要导出的脚本")
            return
        
        script = self.script_manager.get_script(self.current_script_id)
        if not script:
            return
        
        file_path, _ = QFileDialog.getSaveFileName(
            self, "导出脚本", f"{script.name}.json", "JSON文件 (*.json)"
        )
        if file_path:
            if self.script_manager.export_script(self.current_script_id, file_path):
                self.status_bar.showMessage(f"已导出脚本: {script.name}")
    
    def start_recording(self):
        """开始录制"""
        if self.is_recording:
            return
        
        try:
            url, ok = QInputDialog.getText(self, "开始录制", "请输入要录制的网址:")
            if ok and url:
                self.recorder = PlaywrightRecorder(
                    browser_type=self.settings.browser_type,
                    headless=self.settings.headless
                )
                
                # 在单独线程中启动录制
                import threading
                def start_recording_thread():
                    loop = asyncio.new_event_loop()
                    asyncio.set_event_loop(loop)
                    loop.run_until_complete(self.recorder.start_recording(url))
                
                thread = threading.Thread(target=start_recording_thread)
                thread.daemon = True
                thread.start()
                
                self.is_recording = True
                self.recording_started.emit()
                self.status_bar.showMessage("录制中...")
                self.tab_widget.setCurrentWidget(self.recording_widget)
                
        except Exception as e:
            QMessageBox.critical(self, "错误", f"启动录制失败: {str(e)}")
    
    def stop_recording(self):
        """停止录制"""
        if not self.is_recording or not self.recorder:
            return
        
        try:
            # 停止录制并获取动作
            def stop_recording_thread():
                loop = asyncio.new_event_loop()
                asyncio.set_event_loop(loop)
                actions = loop.run_until_complete(self.recorder.stop_recording())
                
                # 在主线程中处理结果
                QTimer.singleShot(0, lambda: self.handle_recording_result(actions))
            
            import threading
            thread = threading.Thread(target=stop_recording_thread)
            thread.daemon = True
            thread.start()
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"停止录制失败: {str(e)}")
    
    def handle_recording_result(self, actions):
        """处理录制结果"""
        try:
            self.is_recording = False
            self.recording_stopped.emit()
            
            if actions:
                # 生成脚本代码
                script_code = self.script_generator.generate_script(actions)
                
                # 创建新脚本或更新当前脚本
                if self.current_script_id:
                    script = self.script_manager.get_script(self.current_script_id)
                    if script:
                        # 更新现有脚本
                        from backend.models import ActionModel
                        for action_data in actions:
                            action = ActionModel(**action_data)
                            script.add_action(action)
                        script.generated_code = script_code
                        self.script_editor_widget.load_script(script)
                else:
                    # 创建新脚本
                    from backend.models import ScriptModel, ActionModel
                    script = ScriptModel(name=f"录制脚本_{len(actions)}动作")
                    for action_data in actions:
                        action = ActionModel(**action_data)
                        script.add_action(action)
                    script.generated_code = script_code
                    
                    self.script_manager.save_script(script)
                    self.current_script_id = script.id
                    self.script_editor_widget.load_script(script)
                    self.script_list_widget.refresh_scripts()
                
                self.status_bar.showMessage(f"录制完成，共录制 {len(actions)} 个动作")
                self.tab_widget.setCurrentWidget(self.script_editor_widget)
            else:
                self.status_bar.showMessage("录制完成，未录制到动作")
                
        except Exception as e:
            QMessageBox.critical(self, "错误", f"处理录制结果失败: {str(e)}")
    
    def run_current_script(self):
        """运行当前脚本"""
        if not self.current_script_id:
            QMessageBox.warning(self, "警告", "请先选择要运行的脚本")
            return
        
        script = self.script_manager.get_script(self.current_script_id)
        if not script or not script.generated_code:
            QMessageBox.warning(self, "警告", "脚本代码为空")
            return
        
        try:
            # 在执行器中运行脚本
            def run_script_thread():
                loop = asyncio.new_event_loop()
                asyncio.set_event_loop(loop)
                result = loop.run_until_complete(
                    self.script_executor.execute_script(script.generated_code)
                )
                
                # 在主线程中处理结果
                QTimer.singleShot(0, lambda: self.handle_execution_result(result))
            
            import threading
            thread = threading.Thread(target=run_script_thread)
            thread.daemon = True
            thread.start()
            
            self.status_bar.showMessage("脚本执行中...")
            self.tab_widget.setCurrentWidget(self.execution_widget)
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"运行脚本失败: {str(e)}")
    
    def handle_execution_result(self, result):
        """处理执行结果"""
        try:
            if result["success"]:
                self.status_bar.showMessage(f"脚本执行成功，耗时 {result['duration']:.2f} 秒")
            else:
                self.status_bar.showMessage(f"脚本执行失败: {result['error']}")
            
            # 更新脚本统计
            if self.current_script_id:
                script = self.script_manager.get_script(self.current_script_id)
                if script:
                    script.update_execution_stats(result["success"])
                    self.script_manager.save_script(script)
            
            # 在执行结果界面显示结果
            self.execution_widget.show_result(result)
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"处理执行结果失败: {str(e)}")
    
    def stop_script_execution(self):
        """停止脚本执行"""
        self.script_executor.stop_execution()
        self.status_bar.showMessage("已停止脚本执行")
    
    def show_settings(self):
        """显示设置"""
        self.tab_widget.setCurrentWidget(self.settings_widget)
    
    def show_about(self):
        """显示关于"""
        QMessageBox.about(self, "关于", f"""
        {self.settings.app_name}
        版本: {self.settings.app_version}
        
        基于Python Playwright的界面自动化管理工具
        """)
    
    def closeEvent(self, event):
        """关闭事件"""
        try:
            # 停止录制和执行
            if self.is_recording:
                self.stop_recording()
            
            self.script_executor.stop_execution()
            
            # 保存当前脚本
            if self.current_script_id:
                self.save_current_script()
            
            event.accept()
            
        except Exception as e:
            logger.error(f"关闭窗口时出错: {e}")
            event.accept()